/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ddbserver.connections;

import ddbserver.DDBServerView;
import ddbserver.common.Site;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
 *
 * @author Roar
 */
public class SiteManager {

    private HashMap<String, Site> siteMap;
    private Properties properties;
    private static SiteManager instance = null;
    private String myself;
    private String myip;
    private int myport;
    private String myname;

    public String getMyip() {
        return myip;
    }

    public void setMyip(String myip) {
        this.myip = myip;
    }

    public String getMyname() {
        return myname;
    }

    public void setMyname(String myname) {
        this.myname = myname;
    }

    public int getMyport() {
        return myport;
    }

    public void setMyport(int myport) {
        this.myport = myport;
    }

    public String getMyself() {
        return myself;
    }

    public void setMyself(String myself) {
        this.myself = myself;
    }

    public static synchronized SiteManager getInstance() {
        if (instance == null) {
            instance = new SiteManager();
        }
        return instance;
    }

    private SiteManager() {
        siteMap = new LinkedHashMap<String, Site>();
        try {
            properties = new Properties();
            if (!new File("sitelist.properties").exists()) {
                new File("sitelist.properties").createNewFile();
                properties.load(new FileInputStream("sitelist.properties"));
                properties.setProperty("sitenum", "0");
                properties.store(new FileOutputStream("sitelist.properties"), null);
            }
            properties.load(new FileInputStream("sitelist.properties"));
            int sitenum = Integer.parseInt(properties.getProperty("sitenum", "0"));
            for (int i = 0; i < sitenum; i++) {
                String line = properties.getProperty("site" + i);
                String[] sub = line.split("\\s");
                String[] ipport = sub[0].split(":");
                Site site = new Site(ipport[0], Integer.parseInt(ipport[1]));
                if (sub.length == 3) {
                    site.setName(sub[1]);
                }
                siteMap.put(sub[0], site);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void saveProperties() {
        try {
            properties.load(new FileInputStream("sitelist.properties"));
            properties.setProperty("sitenum", "" + getSize());
            Set<String> keys = siteMap.keySet();
            int i = 0;
            for (String key : keys) {
                Site site = siteMap.get(key);
                properties.setProperty("site" + i, site.toString());
                i++;
            }
            properties.store(new FileOutputStream("sitelist.properties"), null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Site getSite(String site) {
        site = site.trim();
        site = site.split("\\s")[0].trim();
        return siteMap.get(site);
    }

    public void addSite(String site) {
        site = site.trim();
        String[] sub = site.split("\\s");
        if (!siteMap.containsKey(site)) {
            String[] ipport = sub[0].split(":", 2);
            Site sites = new Site(ipport[0], Integer.parseInt(ipport[1]));
            if (sub.length == 3) {
                sites.setName(sub[1]);
            }
            siteMap.put(sub[0], sites);
            saveProperties();
        }
    }

    public void putSite(String siteInfo) {
        //siteInfo: site1 localhost:1234
        siteInfo = siteInfo.trim();
        String siteName = siteInfo.split("\\s")[0].trim();
        String siteIP = siteInfo.split("\\s")[1].trim().split(":")[0].trim();
        String sitePort = siteInfo.split("\\s")[1].trim().split(":")[1].trim();

        Site site = new Site(siteIP, Integer.parseInt(sitePort));
        site.setName(siteName);
        siteMap.put(siteInfo.split("\\s")[1].trim(), site);
        saveProperties();
    }

    public void removeSite(String site) {
        site = site.trim().split("\\s")[0].trim();
        if (siteMap.containsKey(site)) {
            siteMap.remove(site);
            saveProperties();
        }
    }

    public int getSize() {
        return siteMap.size();
    }

    public List<String> getSites() {
        List<String> res = new ArrayList<String>();
        Set<String> keys = siteMap.keySet();
        for (String key : keys) {
            res.add(siteMap.get(key).toString());
        }
        return res;
    }

    public Site getSiteByName(String siteName) {
        Site site;
        Set<String> keys = siteMap.keySet();
        for(String key : keys) {
            site = siteMap.get(key);
            if(site.getName().equals(siteName)) {
                return site;
            }
        }
        return null;
    }
    public int connect(String site) {
        Site realsite = siteMap.get(site);
        if (realsite != null) {
            if (realsite.connect() == 0) {
                return 0;
            }
            DDBServerView.getInstance().setText("no site " + site.toString());
        }
        return 1;
    }

    public void disconnect(String site) {
        Site realsite = siteMap.get(site);
        if (realsite != null) {
            realsite.disconnect();
        }
        List<Site> connectedSite = getConnectedSite();
        for (Site site1 : connectedSite) {
            site1.newSession();
            site1.send("client");
            site1.send("deactive");
            site1.send(site);
        }
    }

    public void sync(String site) {
        Site realsite = siteMap.get(site);
        if (realsite != null) {
            List<Site> beforesync = getConnectedSite();
            List<String> newsite = new ArrayList<String>();
            realsite.newSession();
            realsite.send("client");
            realsite.send("sync");
            realsite.send("" + beforesync.size());
            for (Site site1 : beforesync) {
                realsite.send(site1.toString());
            }
            int num = Integer.parseInt(realsite.read());
            for (int idx = 0; idx < num; idx++) {
                String line = realsite.read();
                //if (getSite(line) == null || getSite(line).isConnected() == false) {
                    newsite.add(line);
                //}
            }
            for (String string : newsite) {
                addSite(string);
                getSite(string).setConnected(true);
            }
            for (Site st : beforesync) {
                st.newSession();
                st.send("client");
                st.send("active");
                st.send("" + newsite.size());
                for (String string : newsite) {
                    st.send(string);
                }
            }
        }
        DDBServerView.getInstance().refeshServerList();
    }

    public List<Site> getConnectedSite() {
        List<Site> retval = new ArrayList<Site>();
        Set<String> keys = siteMap.keySet();
        for (String ss : keys) {
            if (siteMap.get(ss).isConnected()) {
                retval.add(siteMap.get(ss));
            }
        }
        return retval;
    }
}
